﻿// See https://aka.ms/new-console-template for more information

using netTool.util;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace netTool;

/// <summary>
/// 
/// </summary>
public class Program {


    private static string type = "tcpServer";

    private static string localIp = "127.0.0.1";

    private static ushort port = 9000;

    public static bool echo = false;

    public static string respData = "";

    private static Log Log = new Log();

    public static async Task Main(string[] args) {

        if (args.Length > 0) {
            foreach (string arg in args) {
                if (arg.ToLower().StartsWith("type")) {
                    type = arg.Replace("type=", "");
                }
                else if (arg.ToLower().StartsWith("port")) {
                    port = Convert.ToUInt16(arg.Replace("port=", ""));
                }
                else if (arg.ToLower().StartsWith("echo")) {
                    echo = arg.Replace("echo=", "") == "true";
                }
                else if (arg.ToLower().StartsWith("respData")) {
                    respData = arg.Replace("respData=", "");
                }
                else if (arg.ToLower().StartsWith("help")) {
                    string[] strings = [
                        "./netTool 后面跟参数",
                        "参数说明",
                        "port=20001，侦听的端口，默认值9000",
                        "type=tcpServer，启用方式，默认值tcpServer",
                        "echo=true，是否启用回声模式，如果启用，则客户端发什么，服务器就回什么",
                        "respData=hello，要回复的数据，如果是0x开头则表示是16进制的数据，如果不是，认为是ASCII字符串，如respData=0x010203",
                        "",
                    ];
                    foreach (string s in strings) {
                        Console.WriteLine(s);
                    }
                    return;
                }
            }
        }

        if (type == "tcpServer") {
            // 创建TcpListener实例
            IPAddress localAddr = IPAddress.Parse(localIp);
            TcpListener server = new(localAddr, port);

            Log.Debug("Starting server...");
            // 开始监听传入的连接请求
            server.Start();

            Log.Debug($"Server is listening at {localAddr}:{port}.");

            while (true) {
                try {
                    // 等待客户端连接，并为每个连接启动一个新的任务
                    TcpClient client = await server.AcceptTcpClientAsync();
                    _ = HandleClientAsync(client); // 使用Task来处理每个客户端
                }
                catch (Exception e) {
                    Log.Error(e);
                }
            }
        }
        else {
            Log.Error($"暂不支持当前类型{type}");
        }

    }

    static async Task HandleClientAsync(TcpClient client) {
        NetworkStream stream = client.GetStream();
        byte[] buffer = new byte[1024];
        int bytesRead;
        // 获取客户端的IP地址和端口号
        var clientEndPoint = client.Client.RemoteEndPoint as IPEndPoint;
        string clientIp = clientEndPoint.Address.ToString();
        int port = clientEndPoint.Port;
        Log.Debug($"{clientIp}:{port} Client connected");
        try {
            while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) != 0) {
                // 将字节数组转换为字符串
                byte[] receBuff = new byte[bytesRead];
                Array.Copy(buffer, 0, receBuff, 0, receBuff.Length);
                string dataReceived = Encoding.UTF8.GetString(receBuff);
                Log.Debug($"{clientIp}:{port}↑ Received: {receBuff.ByteToHexString()}[{dataReceived}]");

                // 响应
                if (echo) {
                    // 可选：向客户端回发数据
                    byte[] responseBuffer = receBuff;
                    stream.Write(responseBuffer, 0, responseBuffer.Length);

                    Log.Debug($"{clientIp}:{port}↓ Response: {responseBuffer.ByteToHexString()}");
                }
                else {
                    if (respData.Length > 0) {
                        // 可选：向客户端回发数据
                        if (respData.StartsWith("0x")) {
                            byte[] responseBuffer = respData.Replace("0x", "").ToBytes();
                            stream.Write(responseBuffer, 0, responseBuffer.Length);

                            Log.Debug($"{clientIp}:{port}↓ Response: {responseBuffer.ByteToHexString()}");
                        }
                        else {
                            byte[] responseBuffer = Encoding.UTF8.GetBytes(respData);
                            stream.Write(responseBuffer, 0, responseBuffer.Length);

                            Log.Debug($"{clientIp}:{port}↓ Response: {responseBuffer.ByteToHexString()}[{respData}]");
                        }
                    }
                }
            }
        }
        catch (Exception e) {
            Log.Error(e);
        }
        finally {
            // 关闭客户端连接
            client.Close();
            Log.Debug($"{clientIp}:{port} Client disconnected.");
        }
    }


}

public class Log {

    public void Debug(string msg) {
        Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}  {msg}");
    }

    public void Info(string msg) {
        Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}  {msg}");
    }

    public void Error(string msg) {
        Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}  {msg}");
    }

    public void Error(Exception e) {
        Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}  {e.ToString()}");
    }

}